home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / NTUMIN10.ARJ / LOGMIN_H.C < prev    next >
C/C++ Source or Header  |  1992-03-12  |  18KB  |  530 lines

  1. /****************************************************************************
  2.  *
  3.  *      Program name : LOGMIN_H.C
  4.  *
  5.  *    Written By : Eng-Huat Ong and Kian-Mong Low.
  6.  *
  7.  *      This is the actual minimization algorithm. Variation from the actual
  8.  *    LOGMIN algorithm is as follows:
  9.  *        1.    Minterms with adjacency 0 or 1 is minimised first
  10.  *        2.    Select next minterm with lowest adjacency wrt b-array
  11.  *        3.  If more than 1 such minterms, select one with the lowest
  12.  *            adjacency wrt to a-array
  13.  *        4.    To shrink the CPT, select an adjacent term, mi that has the
  14.  *            largest wi AND is already covered
  15.  *        5.  If more than one such adjacent terms are covered, select one
  16.  *        with the lowest adjacency wrt to b-array
  17.  *          6.  If more than one such adjacenct terms with lowest adjacency,
  18.  *        select one that could cover most of the uncovered minterms
  19.  *        if chosen to shrink away
  20.  *        7.  If non of the adjacent term is covered (see step 4), select
  21.  *        one with the lowest adjacency wrt b-array from the
  22.  *        uncovered adj term at step 4.
  23.  *
  24.  * --------------------------------------------------------------------------
  25.  *    Copyright (c) 1992. All Rights Reserved. Nanyang Technological
  26.  *    University.
  27.  *
  28.  *    You are free to use, copy and distribute this software and its
  29.  *    documentation providing that:
  30.  *
  31.  *        NO FEE IS CHARGED FOR USE, COPYING OR DISTRIBUTION.
  32.  *
  33.  *        IT IS NOT MODIFIED IN ANY WAY.
  34.  *
  35.  *        THE COPYRIGHT NOTICE APPEAR IN ALL COPIES.
  36.  *
  37.  *    This program is provided "AS IS" without any warranty, expressed or
  38.  *    implied, including but not limited to fitness for any particular
  39.  *    purpose.
  40.  *
  41.  *    If you find NTUMIN fast, easy, and useful, a note or comment would be
  42.  *    appreciated. Please send to:
  43.  *
  44.  *        Boon-Tiong Tan or Othman Bin Ahmad
  45.  *        School of EEE
  46.  *        Nanyang Technological University
  47.  *        Nanyang Avenue
  48.  *        Singapore 2263
  49.  *        Republic of Singapore
  50.  *
  51.  ***************************************************************************/
  52.  
  53. #include <stdio.h>
  54. #include <stdlib.h>
  55. #include <string.h>
  56. #define mask8 255
  57.  
  58. unsigned char   *logmin_h(a, b)              /* pointer to a & b array passed */
  59. unsigned char   *a, *b;
  60.  
  61. {
  62.    unsigned short   pterm, ma, mb, *pm, *pm1, *pm2, pos, pos1;
  63.    unsigned  long   m, k, count, count1, topow();
  64.    register  long   i, wo, wi;
  65.    register  char   j;
  66.          char   test;
  67.    unsigned  char   adjacency();
  68.    unsigned  char   *c, *c1, *d, *e, *s, *temp, adj0, adji;
  69.    unsigned  char   n, adj, nspm, cover, countb, countc;
  70.    unsigned  char   *adjacent(), *reduce(), *cpt(), *ssm(), adj_of_mi();
  71.  
  72.  
  73.    mb = *(b+2)<<8 | *(b+1);            /* no. of minterms in b-array */
  74.  
  75.    n    = *a;                          /* no. of variables */
  76.    nspm = *(a+3);                      /* no. of bytes/minterm */
  77.    ma = *(a+2)<<8 | *(a+1);            /* no. of minterms in a-array */
  78.  
  79.    temp = (unsigned char *) malloc(nspm+1);        /* temporary storage */
  80.    if (temp == 0)
  81.       {
  82.      printf("Out of memory -- LOGMIN_H, *temp\n");
  83.      printf("Program terminated - 1\n");
  84.      exit(0);
  85.       }
  86.  
  87.    s = (unsigned char *) malloc(4);                /* header of s-array */
  88.    if (s == 0)
  89.       {
  90.      printf("Out of memory -- LOGMIN_H, *s\n");
  91.      printf("Program terminated - 2\n");
  92.      exit(0);
  93.       }
  94.  
  95.    pterm = 0;                                /* no. of product term */
  96.  
  97.    /***
  98.     ***  MINIMIZE ALL MINTERMS WITH ADJACENCY OF 0 & 1 FIRST
  99.     ***/
  100.  
  101.    for (i=0; i<mb; i++)                      /* for adj = 0 or 1 */
  102.       {
  103.      *b = n;                             /* assign back to n */
  104.  
  105.      memcpy(temp, (b+4+nspm*i), nspm);   /* pick a minterm from b-array */
  106.      c = adjacent(temp, a, 1);           /* obtain the adjacent terms */
  107.      adj = *(c+1);                       /* adjacency of minterm */
  108.  
  109.      if (adj <= 1)                       /* adjacency 0 or 1 */
  110.         {
  111.            d = cpt(c);                   /* generate CPT */
  112.  
  113.            s = (unsigned char *) realloc(s,4+n*(pterm+1));   /* more space */
  114.            if (s == 0)
  115.           {
  116.              printf("Out of memory -- LOGMIN_H, *s\n");
  117.              printf("Program terminated - 3\n");
  118.              exit(0);
  119.           }
  120.            memcpy ((s+4+n*pterm),d,n);   /* add CPT to soln array */
  121.            pterm++;                      /* product term count */
  122.  
  123.            b = reduce(c,b,i);            /* remove minterms covered from b-array */
  124.            i = (char) *b;                /* index pointer of b-array */
  125.            mb = *(b+2)<<8 | *(b+1);      /* value of mb altered in b-array */
  126.  
  127.            free(d);                    /* free pointer */
  128.         }
  129.      free(c);                            /* free pointer */
  130.       }
  131.  
  132.     /***
  133.      ***  MINIMIZE MINTERMS WITH ADJACENCY GREATER THAN 1
  134.      ***/
  135.  
  136.     while (mb > 0)
  137.        {
  138.       adj0 = 255;                     /* max for 8-bit */
  139.  
  140.       *b = n;                         /* assign back to n */
  141.  
  142.       /***
  143.        ***  OBTAIN AN ARRAY, PM OF POSITION OF ADJACENT TERMS WITH THE LOWEST
  144.        ***  ADJACENCY WRT B-ARRAY
  145.        ***/
  146.  
  147.       for (i=0; i<mb; i++)
  148.          {
  149.         memcpy(temp, (b+4+nspm*i), nspm);    /* pick a minterm */
  150.         adji = adjacency(temp, b);           /* adj wrt b-array */
  151.  
  152.         if (adji<adj0)                       /* look for lowest adj */
  153.            {
  154.               if (adj0!=255)                 /* not the 1st term */
  155.              free(pm);
  156.  
  157.               adj0 = adji;                   /* update lowest adj */
  158.               count = 1;                        /* set count to 1 */
  159.               pm = (unsigned short *) malloc(2);   /* space for pos */
  160.               if (pm == 0)
  161.              {
  162.                 printf("Out of memory -- LOGMIN_H, *pm\n");
  163.                 printf("Program terminated - 4\n");
  164.                 exit(0);
  165.              }
  166.               *pm = i;                       /* 1st pos of minterm */
  167.            }
  168.  
  169.         else if (adji==adj0)                 /* adjacency as low */
  170.            {
  171.               count++;                       /* no. of elements in pm-array */
  172.               pm = (unsigned short*) realloc(pm, 2*count);    /* more space */
  173.               if (pm == 0)
  174.              {
  175.                 printf("Out of memory -- LOGMIN_H, *pm\n");
  176.                 printf("Program terminated - 5\n");
  177.                 exit(0);
  178.              }
  179.               *(pm+count-1) = i;             /* elements in pm-array */
  180.            }
  181.          }
  182.  
  183.       if (count==1)                  /* if only 1 element in pm-array */
  184.          pos = *pm;
  185.       else
  186.          {
  187.         /***
  188.          ***  FORM PM-ARRAY, SELECT THE 1ST ADJACENT TERM THAT HAS THE
  189.          ***  LOWEST ADJACENCY WRT A-ARRAY
  190.          ***/
  191.  
  192.         adj0 = 255;                      /* max for 8-bit */
  193.         for (i=0; i<count; i++)          /* do for all in pm-array */
  194.            {
  195.               memcpy(temp, (b+4+nspm*(*(pm+i))), nspm);
  196.               adji = adjacency(temp, a);          /* adj wrt a-array */
  197.  
  198.               if (adji<adj0)                      /* new lowest found */
  199.              {
  200.                 adj0 = adji;                  /* update lowest */
  201.                 pos = *(pm+i);                /* position of required minterm */
  202.              }
  203.            }
  204.          }
  205.        free(pm);
  206.  
  207.        memcpy(temp, (b+4+nspm*pos), nspm);       /* pick the required minterm */
  208.  
  209.        /***
  210.         ***  GENERATE SSM AND TEST FOR COVERAGE BY FUNCTION
  211.         ***/
  212.  
  213.        c = adjacent(temp, a, 255);          /* obtain adjacent terms */
  214.        adj = *(c+1);                        /* adjacency of minterms */
  215.        d = cpt(c);                          /* generate CPT */
  216.        e = ssm(d);                          /* generate SSM */
  217.        m = topow(*(e+1));                   /* no. of SSM terms */
  218.  
  219.        for (j=0; j<m; j++)                  /* check for SSM coverage */
  220.           {
  221.          memcpy (temp, (e+4+nspm*j), nspm);
  222.          test = exist (temp, a, ma);
  223.          if (test == -1)                /* SSM term not in a-array */
  224.              break;
  225.           }
  226.  
  227.        /***
  228.         ***  ALL SSM COVERED BY THE FUNCTION, SELECT CPT AS PRODUCT TERM
  229.         ***/
  230.  
  231.        if (test == 0)                       /* all SSM's covered by fn */
  232.           {
  233.          if (m > 65536)                 /* too many SSM terms */
  234.             {
  235.                printf("Product Term Too Huge \n");
  236.                printf("Program terminated \n");
  237.                exit(0);
  238.             }
  239.          *(e+1) = (m-1) & mask8;        /* no. of SSM terms minus 1 */
  240.          *(e+2) = (m-1)>>8 & mask8;
  241.          b = reduce(e,b,i);             /* reduce minterms covered from b-array */
  242.          mb = *(b+2)<<8 | *(b+1);       /* no. of minterms in b-array */
  243.  
  244.          s = (unsigned char *) realloc(s, 4+n*(pterm+1)); /* more space */
  245.          if (s == 0)
  246.             {
  247.                printf("Out of memory -- LOGMIN_H, *s\n");
  248.                printf("Program terminated - 6\n");
  249.                exit(0);
  250.             }
  251.          memcpy((s+4+n*pterm),d,n);     /* add CPT to soln array */
  252.          pterm++;                       /* no. of product terms */
  253.  
  254.          free(d);                       /* free pointers */
  255.          free(e);
  256.           }
  257.        else
  258.           {
  259.          /***
  260.           ***  SSM NOT COVERED BY THE FUNCTION
  261.           ***/
  262.  
  263.          free(d);                       /* free pointer */
  264.          cover =0;                      /* coverage status */
  265.  
  266.          while (!cover)        /* do until shrinked SSM is covered */
  267.             {
  268.                /***
  269.             ***  OBTAIN AN ARRAY, PM OF POSITIONS OF ADJACENT TERMS, MI WITH THE LARGEST WI
  270.             ***/
  271.  
  272.                wo = -1;                        /* initial value */
  273.                for (j=0; j<adj; j++)           /* do for all adjacent terms */
  274.               {
  275.                  memcpy(temp,(c+4+nspm*(j+1)),nspm); /* pick adjacent term */
  276.  
  277.                  wi = adj_of_mi(temp,e,a);           /* obtain wi */
  278.                  if (wi>wo)
  279.                 {
  280.                    if (wo != -1)                 /* not the first */
  281.                       free(pm);
  282.                    wo = wi;                      /* new lowest value */
  283.                    count = 1;                    /* reset count to 1 */
  284.  
  285.                    pm = (unsigned short *) malloc(2);  /* space for pm */
  286.                    if (pm==0)
  287.                       {
  288.                      printf("Out of memory -- LOGMIN_H, *pm\n");
  289.                      printf("Program terminated - 7\n");
  290.                      exit(0);
  291.                       }
  292.                    *pm = j;                      /* first element */
  293.                 }
  294.                  else if (wi==wo)                    /* wi as large */
  295.                 {
  296.                    count++;                      /* no. of element in pm-array */
  297.  
  298.                    pm = (unsigned short *) realloc (pm, 2*count);  /* more space */
  299.                    if (pm==0)
  300.                       {
  301.                      printf("Out of memory -- LOGMIN_H, *pm\n");
  302.                      printf("Program terminated - 8\n");
  303.                      exit(0);
  304.                       }
  305.                    *(pm+count-1) = j;            /* elements of pm-array */
  306.                 }
  307.               }
  308.                free(e);                                  /* free pointer */
  309.  
  310.                /***
  311.             ***  DETERMINE FROM PM-ARRAY, AN ARRAY, PM1 OF POSITION OF ADJACENT TERMS
  312.             ***  THAT HAVE ALREADY BEEN COVERED
  313.             ***/
  314.  
  315.                pm1 = (unsigned short *) malloc(2);       /* space for pm1 */
  316.                if (pm1==0)
  317.               {
  318.                  printf("Out of memory -- LOGMIN_H, *pm1\n");
  319.                  printf("Program terminated - 9\n");
  320.                  exit(0);
  321.               }
  322.  
  323.                k = 0;
  324.                for (j=0; j<count; j++)              /* do for all element in pm-array */
  325.               {
  326.                  memcpy(temp, (c+4+nspm*(1+ *(pm+j))), nspm);    /* pick adj term */
  327.                  test = exist(temp,b,mb);
  328.                  if (test == -1)                               /* already covered */
  329.                 {
  330.                    memcpy((pm1+k++), (pm+j), 2);       /* transfer pos to pm1 */
  331.  
  332.                    pm1 = (unsigned short *) realloc(pm1, 2*(k+1)); /*  more space */
  333.                    if (pm1==0)
  334.                       {
  335.                      printf("Out of memory -- LOGMIN_H, *pm1\n");
  336.                      printf("Program terminated - 10\n");
  337.                      exit(0);
  338.                       }
  339.                 }
  340.               }
  341.  
  342.                /***
  343.             ***  OBTAIN FROM PM1-ARRAY, AN ARRAY PM2 OF ADJACENT TERMS, MI WITH
  344.             ***  THE LOWEST ADJACENCY WRT B-ARRAY
  345.             ***/
  346.  
  347.                if (k != 0)                              /* some elements in pm1 */
  348.               {
  349.                  pm2 = (unsigned short *) malloc(2*k);     /* space for pm2 */
  350.                  if (pm2==0)
  351.                 {
  352.                    printf("Out of memory -- LOGMIN_H, *pm2\n");
  353.                    printf("Program terminated - 11\n");
  354.                    exit(0);
  355.                 }
  356.  
  357.                  adj0 = 255;                               /* max of 8-bit */
  358.                  for (j=0; j<k; j++)          /* all elements in pm1-array */
  359.                 {
  360.                    memcpy(temp, (c+4+nspm*(1+*(pm1+j))),nspm);  /* pick adj term */
  361.                    adji = adjacency(temp,b);                  /* adj wrt b-array */
  362.  
  363.                    if (adji<adj0)                              /* new lowest adj */
  364.                       {
  365.                      count1 = 1;                           /* no. in pm2-array */
  366.                      adj0 = adji;                          /* update lowest */
  367.                      *pm2 = *(pm1+j);                      /* element in pm2 */
  368.                       }
  369.                    else if (adji==adj0)                        /* adj as small */
  370.                       {
  371.                      count1++;                             /* no. in pm2-array */
  372.                      *(pm2+count1-1) = *(pm1+j);           /* element in pm2 */
  373.                       }
  374.                 }
  375.                  free(pm1);                    /* free pointer */
  376.  
  377.                  if (count1 == 1)              /* only 1 element in pm2-array */
  378.                 pos = *pm2;                /* position of required adj term */
  379.                  else
  380.                 {
  381.                    /***
  382.                     ***   SHRINK CPT, TAKING EACH OF THE CORRESPONDING ADJACENT
  383.                     ***   TERMS IN PM2-ARRAY AND TAKE THE ONE WHOSE SHRINKED CPT
  384.                     ***   COVERS MOST OF THE TERMS IN B-ARRAY
  385.                     ***/
  386.  
  387.                    countc = 0;                      /* lowest value */
  388.  
  389.                    c1 = (unsigned char *) malloc(4+(*(c+1)+1)*nspm);  /* space for adj terms */
  390.                    if (c1==0)
  391.                       {
  392.                      printf("Out of memory -- LOGMIN_H, *c1\n");
  393.                      printf("Program terminated - 12\n");
  394.                      exit(0);
  395.                       }
  396.  
  397.                    for (j=0; j<count1; j++)             /* all elements in pm2-array */
  398.                       {
  399.                      memcpy(c1, c, 4+nspm*(1+ *(c+1)));         /* pick adj term */
  400.                      *(c1+1) = *(c+1)-1;                  /* decrement adjacency */
  401.  
  402.                      pos1 = *(pm2+j);                     /* adj term to shrink in turn */
  403.                      memcpy ((c1+4+nspm*(1+pos1)), (c1+4+nspm*(2+pos1)), nspm*(*(c1+1)-pos1));
  404.  
  405.                      d = cpt(c1);                         /* generate shrinked CPT */
  406.                      e = ssm(d);                          /* generate shrinked SSM */
  407.                      m = topow (*(e+1));                  /* no. of SSM terms */
  408.  
  409.                      countb = 0;                          /* reset counter */
  410.  
  411.                      for (i=0; i<m; i++)                  /* do for all SSM's in e-array */
  412.                         {
  413.                            memcpy(temp, (e+4+nspm*i), nspm);   /* pick SSM term */
  414.                            test = exist(temp, b, mb);
  415.                            if (test==0)                        /* still in b-array */
  416.                           countb++;                        /* coverage count */
  417.                         }
  418.  
  419.                      if (countb>=countc)             /* largest count found */
  420.                         {
  421.                            countc = countb;          /* update largest count */
  422.                            pos = pos1;               /* required pos of adj term */
  423.                         }
  424.                      free(d);                /* free pointers */
  425.                      free(e);
  426.                       }
  427.                    free(c1);           /* free pointer */
  428.                 }
  429.                  free(pm2);                /* free pointer */
  430.               }
  431.                else                            /* non in pm1-array */
  432.               {
  433.                  /***
  434.                   ***  ALL TERMS IN PM-ARRAY HAS NOT BEEN COVERED, SELECT ONE
  435.                   ***  WITH THE LOWEST ADJACENCY WRT B-ARRAY
  436.                   ***/
  437.  
  438.                  adj0 = 255;                /* max for 8-bit */
  439.                  for (j=0; j<count; j++)    /* all in pm-aaray */
  440.                 {
  441.                    memcpy(temp, (c+4+nspm*(1+ *(pm+j))), nspm);  /* pick adj term */
  442.                    adji = adjacency(temp, b);                    /* adj wrt b-array */
  443.  
  444.                    if (adji<adj0)              /* lowest adj found */
  445.                       {
  446.                      adj0 = adji;          /* update lowest */
  447.                      pos = *(pm+j);        /* required position of adj term */
  448.                       }
  449.                 }
  450.               }
  451.                free(pm);                 /* free pointer */
  452.  
  453.                adj--;                    /* no. of adj term after shrinking */
  454.                *(c+1) = adj;             /* adjacency after shrinking */
  455.  
  456.                /***
  457.             ***  SHRINK CPT (REMOVE THE SELECTED ADJACENT TERM FROM C-ARRAY),
  458.             ***  GENERATE NEW CPT, SSM AND TEST FOR COVERAGE BY FUNCTION
  459.             ***/
  460.  
  461.                memcpy((c+4+nspm*(1+pos)), (c+4+nspm*(2+pos)), nspm*(adj-pos));  /* shrink CPT */
  462.  
  463.                c = (unsigned char*) realloc(c, 4+nspm*(1+adj));   /* reduce space */
  464.                if (c==0)
  465.               {
  466.                  printf("Out of memory -- LOGMIN_H, *c\n");
  467.                  printf("Program terminated - 13\n");
  468.                  exit(0);
  469.               }
  470.  
  471.                d = cpt(c);                  /* generate CPT */
  472.                e = ssm(d);                  /* generate SSM */
  473.                m = topow(*(e+1));           /* no. of SSM terms */
  474.  
  475.                for (i=0; i<m; i++)          /* check SSM coverage by function */
  476.               {
  477.                  memcpy(temp, (e+4+nspm*i), nspm);  /* pick SSM term */
  478.                  test = exist(temp,a,ma);
  479.                  if (test == -1)                    /* SSM term not covered */
  480.                 break;
  481.               }
  482.  
  483.                /***
  484.             ***  SHRINKED SSM COVERED BY FUNCTION, REDUCE B-ARRAY
  485.             ***  AND SELECT SHRINKED CPT AS PRODUCT TERM
  486.             ***/
  487.  
  488.                if (test==0)                   /* SSM covered */
  489.               {
  490.                  if (m > 65536)                  /* too many SSM terms */
  491.                 {
  492.                    printf("Product Term Too Huge \n");
  493.                    printf("Program terminated \n");
  494.                    exit(0);
  495.                 }
  496.                  *(e+1) = (m-1) & mask8;         /* no. of SSM terms minus 1 */
  497.                  *(e+2) = (m-1)>>8 & mask8;
  498.                  b = reduce(e, b, i);     /* remove minterms covered from b-array */
  499.                  mb = *(b+2)<<8 | *(b+1); /* no. of minterms in b-array */
  500.  
  501.                  s = (unsigned char *) realloc(s, 4+n*(pterm+1));  /* more space */
  502.                  if (s==0)
  503.                 {
  504.                    printf("Out of memory -- LOGMIN_H, *s\n");
  505.                    printf("Program terminated - 14\n");
  506.                    exit(0);
  507.                 }
  508.                  memcpy ((s+4+n*pterm), d, n);      /* add shrinked CPT to soln array */
  509.                  pterm++;                           /* no. of product terms */
  510.  
  511.                  cover = 1;                         /* coverage status */
  512.                  free(e);                           /* free pointer */
  513.               }
  514.                free (d);                      /* free pointer */
  515.             }
  516.           }
  517.       free(c);                   /* free pointer */
  518.       }
  519.    *s = n;                           /* no. of variables */
  520.    *(s+1) = pterm & mask8;           /* no. of product terms in 2 bytes */
  521.    *(s+2) = pterm>>8 & mask8;
  522.  
  523.    free(temp);                       /* free pointer */
  524.    free(a);
  525.    free(b);
  526.  
  527.    return(s);                        /* return solution array */
  528. }
  529.  
  530.